package com.chinackts.common.okhttp;

import com.alibaba.fastjson.JSONObject;
import com.chinackts.common.exception.OkhttpReqException;
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.annotation.Retryable;

/**
 * @author lianhong
 * @since 2018/12/17
 */
public class OkHttpRequest {

    private static final Logger LOGGER = LoggerFactory.getLogger(OkHttpRequest.class);

    private final OkHttpClient okHttpClient;

    public OkHttpRequest(OkHttpClient okHttpClient) {
        this.okHttpClient = okHttpClient;
    }

    /**
     * 根据map获取get请求参数
     */
    public StringBuffer getQueryString(String url, JSONObject queries) {
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && !queries.keySet().isEmpty()) {
            boolean firstFlag = true;
            for (String key : queries.keySet()) {
                if (firstFlag) {
                    sb.append("?").append(key).append("=").append(queries.get(key));
                    firstFlag = false;
                } else {
                    sb.append("&").append(key).append("=").append(queries.get(key));
                }
            }
        }
        return sb;
    }

    /**
     * 调用okhttp的newCall方法
     */
    @Retryable(value = OkhttpReqException.class, maxAttempts = 2)
    private String execNewCall(Request request) {
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response == null || response.body() == null){
                LOGGER.warn("请求：{}， 响应为空", request.url());
                throw new OkhttpReqException("请求异常, 重试");
            }
            if (response.isSuccessful()) {
                return response.body().string();
            } else if (response.isRedirect()) {
                String url = response.headers("location").isEmpty() ? "" : response.headers("location").get(0);
                if (response.body() != null) {
                    response.close();
                }
                if (!url.isEmpty()) {
                    request.newBuilder().url(url);
                    return execNewCall(request);
                }
            }
            LOGGER.warn("请求：{}， 响应码：{}", request.url(), response.code());
        } catch (Exception e) {
            LOGGER.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
        }
        return "";
    }

    /**
     * get
     *
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     */
    public String get(String url, JSONObject queries) {
        StringBuffer sb = getQueryString(url, queries);
        Request request = new Request.Builder()
                .url(sb.toString())
                .build();
        return execNewCall(request);
    }

    /**
     * delete
     */
    public String delete(String url) {
        Request request = new Request.Builder().url(url).delete().build();
        return execNewCall(request);
    }

    /**
     * get
     */
    public byte[] get(String url) {
        Request request = new Request.Builder().url(url).build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().bytes();
            }
        } catch (Exception e) {
            LOGGER.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
        }
        return null;
    }

    /**
     * put
     */
    public String put(String url, String jsonParams) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = new Request.Builder().url(url).put(requestBody).build();
        return execNewCall(request);
    }

    /**
     * post
     */
    public String post(String url, JSONObject params) {
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (params != null && !params.keySet().isEmpty()) {
            for (String key : params.keySet()) {
                builder.add(key, params.getString(key));
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        return execNewCall(request);
    }

    /**
     * post
     */
    public byte[] postBytes(String url, JSONObject params) {
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (params != null && !params.keySet().isEmpty()) {
            for (String key : params.keySet()) {
                builder.add(key, params.getString(key));
            }
        }
        Request request = new Request.Builder().url(url).post(builder.build()).build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful() && response.body() != null) {
                return response.body().bytes();
            }
        } catch (Exception e) {
            LOGGER.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
        }
        return null;
    }

    /**
     * post请求发送json数据
     */
    public String post(String url, String jsonParams) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        return execNewCall(request);
    }

}
